import axios from 'axios';
import { ElNotification, ElMessageBox } from 'element-plus';
import cookie from '@/utils/tool';
import router from '@/router';

axios.defaults.baseURL = ''
axios.defaults.timeout = 3000000

// 节流控制
const throttleMap = new Map();
const throttle = (fn, delay = 1000) => {
  return function (url, data = {}, config = {}) {
    const key = `${fn.name}-${url}`;
    if (!throttleMap.has(key) || Date.now() - throttleMap.get(key) > delay) {
      throttleMap.set(key, Date.now());
      return fn.call(this, url, data, config);
    }
    return Promise.reject(new Error('请求被节流，请稍后再试'));
  }
};
// HTTP request 拦截器
axios.interceptors.request.use(
  (config) => {
    let token = cookie.get("TOKEN");
    if (token) {
      // config.headers.Authorization = 'Bearer' + token
      config.headers.token = token
    }
    if (config.method == 'get') {
      config.params = config.params || {};
      config.params['_'] = new Date().getTime();
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

//FIX 多个API同时401时疯狂弹窗BUG
let MessageBox_401_show = false

// HTTP response 拦截器
axios.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    if (error.response) {
      if (error.response.status == 404) {
        ElNotification.error({
          title: '请求错误',
          message: "Status:404，正在请求不存在的服务器记录！"
        });
      } else if (error.response.status == 500) {
        ElNotification.error({
          title: '请求错误',
          message: error.response.data.message || "Status:500，服务器发生错误！"
        });
      } else if (error.response.status == 401) {
        if (!MessageBox_401_show) {
          MessageBox_401_show = true
          ElMessageBox.confirm('当前用户已被登出或无权限访问当前资源，请尝试重新登录后再操作。', '无权限访问', {
            type: 'error',
            closeOnClickModal: false,
            center: true,
            confirmButtonText: '重新登录',
            beforeClose: (action, instance, done) => {
              MessageBox_401_show = false
              done()
            }
          }).then(() => {
            router.replace({ path: '/login' });
          }).catch(() => { })
        }
      } else {
        ElNotification.error({
          title: '请求错误',
          message: error.message || `Status:${error.response.status}，未知错误！`
        });
      }
    } else {
      ElNotification.error({
        title: '请求错误',
        message: "请求服务器无响应！"
      });
    }

    return Promise.reject(error.response);
  }
);

var http = {

  /** get 请求
   * @param  {string} url 接口地址
   * @param  {object} params 请求参数
   * @param  {object} config 参数
   */
  get: throttle(function get(url, params = {}, config = {}) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'get',
        url: url,
        params: params,
        ...config
      }).then((response) => {
        resolve(response.data);
      }).catch((error) => {
        reject(error);
      })
    })
  }),

  /** post 请求
   * @param  {string} url 接口地址
   * @param  {object} data 请求参数
   * @param  {object} config 参数
   */
  post: throttle(function post(url, data = {}, config = {}) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'post',
        url: url,
        data: data,
        ...config
      }).then((response) => {
        resolve(response.data);
      }).catch((error) => {
        reject(error);
      })
    })
  }),

  /** put 请求
   * @param  {string} url 接口地址
   * @param  {object} data 请求参数
   * @param  {object} config 参数
   */
  put: throttle(function put(url, data = {}, config = {}) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'put',
        url: url,
        data: data,
        ...config
      }).then((response) => {
        resolve(response.data);
      }).catch((error) => {
        reject(error);
      })
    })
  }),

  /** patch 请求
   * @param  {string} url 接口地址
   * @param  {object} data 请求参数
   * @param  {object} config 参数
   */
  patch: throttle(function patch(url, data = {}, config = {}) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'patch',
        url: url,
        data: data,
        ...config
      }).then((response) => {
        resolve(response.data);
      }).catch((error) => {
        reject(error);
      })
    })
  }),

  /** delete 请求
   * @param  {string} url 接口地址
   * @param  {object} data 请求参数
   * @param  {object} config 参数
   */
  delete: throttle(function del(url, data = {}, config = {}) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'delete',
        url: url,
        data: data,
        ...config
      }).then((response) => {
        resolve(response.data);
      }).catch((error) => {
        reject(error);
      })
    })
  }),
}

export default http;
